﻿// ===============================================================================
// TagFinder.cs
// EOS Web Framework
// ===============================================================================
// Copyright (c) EOS Development Group. All rights reserved.
// ===============================================================================

namespace EOS.Framework.Web.Mvc.Rendering
{
    using System;
    using System.Collections.Generic;
    using System.Text.RegularExpressions;
    using EOS.Framework.Tools;

    /// <summary>
    /// Helper class for finding tags.
    /// </summary>
    public static class MarkupHelper
    {
        /// <summary>
        /// Finds all values in the specified text.
        /// </summary>
        /// <param name="text">The text to check.</param>
        /// <returns>A list of all values.</returns>
        /// <remarks>A value is indicated this way: #{VALUE}.</remarks>
        public static List<string> FindValues(string text)
        {
            List<string> values = new List<string>();

            if (text != null)
            {
                int index = 0;

                bool found = true;
                while (found)
                {
                    int valueOpenIndex = text.IndexOf("#{", index);
                    if (valueOpenIndex >= 0)
                    {
                        int tagCloseIndex = text.IndexOf("}", index + 1);

                        values.Add(text.Substring(valueOpenIndex + 2, tagCloseIndex - valueOpenIndex - 2));
                        index = tagCloseIndex;
                    }
                    else
                    {
                        found = false;
                    }
                }
            }

            return values;
        }

        /// <summary>
        /// Tries to find all tags in the specified xml.
        /// </summary>
        /// <param name="xml">The XML where the tags should be find in. Cannot be null
        /// or empty and cannot contains blanks only.</param>
        /// <returns>A list of all tag names in the specified XML string.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="xml"/> is null
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="ArgumentException"><paramref name="xml"/> is a string of length
        /// 0 or contains only blanks.</exception>
        public static List<string> FindTags(string xml)
        {
            if (xml == null)
            {
                throw new ArgumentNullException("xml");
            }

            if (StringHelper.IsEmptyOrBlanksOnly(xml))
            {
                throw new ArgumentException(Properties.Resources.EmptyStringParameter, "xml");
            }

            List<string> tags = new List<string>();

            int index = 0;

            bool found = true;
            while (found)
            {
                int tagOpenIndex = xml.IndexOf("<", index);
                if (tagOpenIndex >= 0)
                {
                    int tagCloseIndex = xml.IndexOf(">", index + 1);

                    string subString = xml.Substring(tagOpenIndex + 1, tagCloseIndex - tagOpenIndex - 1).Trim();
                    if (subString.StartsWith("/") == false)
                    {
                        if (subString.StartsWith(Constants.HtmlButton) ||
                            subString.StartsWith(Constants.HtmlInput) ||
                            subString.StartsWith(Constants.HtmlSelect) ||
                            subString.StartsWith(Constants.HtmlTextarea))
                        {
                            Regex regex = new Regex("name[\\s]*=[\\s]*\"?(?<id>[\\w]+)?", RegexOptions.Compiled);

                            Match m = regex.Match(subString);
                            if (m != null && m.Success)
                            {
                                string id = m.Result("${id}");
                                if (string.IsNullOrEmpty(id) == false)
                                {
                                    tags.Add(id);
                                }
                            }
                        }
                        else
                        {
                            Regex regex = new Regex("mvc:id[\\s]*=[\\s]*\"?(?<id>[\\w]+)?", RegexOptions.Compiled);

                            Match m = regex.Match(subString);
                            if (m != null && m.Success)
                            {
                                string id = m.Result("${id}");
                                if (string.IsNullOrEmpty(id) == false)
                                {
                                    tags.Add(id);
                                }
                            }
                        }
                    }

                    index = tagCloseIndex;
                }
                else
                {
                    found = false;
                }
            }

            return tags;
        }
    }
}
